# coding: utf-8
from PySide6.QtCore import Signal, Qt, Property, QEvent, QSize
from PySide6.QtGui import QColor
from PySide6.QtWidgets import QLineEdit, QTextEdit, QTextBrowser, QPlainTextEdit, QWidget
from qfluentwidgets import FluentIcon as FIF, setFont, SmoothScrollDelegate, CaptionLabel
from qfluentwidgets.components.widgets.line_edit import LineEdit, LineEditButton, TextEditMenu

from ...common import ElStyleSheet, ElIcon


class NotNoneLineEditBase:
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._isChickNull = False

        self.warningLabel = CaptionLabel("输入框不能为空", self)
        self.warningLabel.hide()
        self.warningLabel.setTextColor("#cf1010", QColor(255, 28, 32))
        self.textChanged.connect(self.checkText)

    def checkText(self):
        if not self.text().strip():
            self.warningLabel.show()
        else:
            self.warningLabel.hide()

    def setWarningText(self, text: str):
        self.warningLabel.setText(text)

    def getWarningText(self) -> str:
        return self.warningLabel.text()

    def setWarningVisible(self, visible: bool):
        self.warningLabel.setVisible(visible)

    def isWarningVisible(self) -> bool:
        return self.warningLabel.isVisible()

    def isNull(self) -> bool:
        if self.isCheckNull():
            return not self.text().strip()
        else:
            return False

    def setCheckNull(self, null: bool):
        self._isChickNull = null

    def isCheckNull(self) -> bool:
        return self._isChickNull

    def resizeEvent(self, event):
        self.warningLabel.move(10, self.height() - self.warningLabel.height())
        super().resizeEvent(event)


class ElLineEdit(LineEdit):
    def __init__(self, parent=None):
        super().__init__(parent)
        ElStyleSheet.LINE_EDIT.apply(self)
        self.clearButton.setFixedSize(30, 30)
        self.setFixedHeight(40)
        self.hBoxLayout.setContentsMargins(6, 4, 6, 4)

    def paintEvent(self, event):
        QLineEdit.paintEvent(self, event)

    def setLayoutContentsMargins(self, left: int, top: int, right: int, bottom: int):
        self.hBoxLayout.setContentsMargins(left, top, right, bottom)

    def setLayoutSpacing(self, spacing: int):
        self.hBoxLayout.setSpacing(spacing)

    def addWidget(self, widget: QWidget, position=QLineEdit.ActionPosition.TrailingPosition):
        # widget.setFixedHeight(30)
        if position == QLineEdit.ActionPosition.LeadingPosition:
            self.hBoxLayout.insertWidget(len(self.leftButtons), widget, 0, Qt.AlignLeft)
            if not self.leftButtons:
                self.hBoxLayout.insertStretch(1, 1)

            self.leftButtons.append(widget)
        else:
            self.rightButtons.append(widget)
            self.hBoxLayout.addWidget(widget, 0, Qt.AlignRight)

        self._adjustTextMargins()

    def _adjustTextMargins(self):
        left = sum(
            [button.width() + self.hBoxLayout.spacing() for button in self.leftButtons]) - self.hBoxLayout.spacing()
        right = sum([button.width() + self.hBoxLayout.spacing() for button in
                     self.rightButtons]) + 28 * self.isClearButtonEnabled()
        m = self.textMargins()
        self.setTextMargins(left, m.top(), right, m.bottom())


class ElSearchLineEdit(ElLineEdit):
    """ Search line edit """

    searchSignal = Signal(str)
    clearSignal = Signal()

    def __init__(self, parent=None):
        super().__init__(parent)
        self.searchButton = LineEditButton(ElIcon.Search, self)
        self.searchButton.setFixedSize(30, 30)

        self.hBoxLayout.addWidget(self.searchButton, 0, Qt.AlignRight)
        self.setClearButtonEnabled(True)
        self.setTextMargins(0, 0, 59, 0)

        self.searchButton.clicked.connect(self.search)
        self.clearButton.clicked.connect(self.clearSignal)

    def search(self):
        """ emit search signal """
        text = self.text().strip()
        if text:
            self.searchSignal.emit(text)
        else:
            self.clearSignal.emit()

    def setClearButtonEnabled(self, enable: bool):
        self._isClearButtonEnabled = enable
        self.setTextMargins(0, 0, 28 * enable + 30, 0)

    def setSearchButtonPosition(self, position: QLineEdit.ActionPosition = QLineEdit.ActionPosition.TrailingPosition):
        self.hBoxLayout.removeWidget(self.searchButton)
        if position == QLineEdit.ActionPosition.LeadingPosition:
            self.addWidget(self.searchButton, position)
        else:
            self.hBoxLayout.addWidget(self.searchButton, 0, Qt.AlignRight)


class ElTextEdit(QTextEdit):
    """ Text edit """

    def __init__(self, parent=None):
        super().__init__(parent=parent)
        self.scrollDelegate = SmoothScrollDelegate(self)
        ElStyleSheet.LINE_EDIT.apply(self)
        setFont(self)

    def contextMenuEvent(self, e):
        menu = TextEditMenu(self)
        menu.exec(e.globalPos(), ani=True)

    def paintEvent(self, event):
        QTextEdit.paintEvent(self, event)


class ElPlainTextEdit(QPlainTextEdit):
    """ Plain text edit """

    def __init__(self, parent=None):
        super().__init__(parent=parent)
        self.scrollDelegate = SmoothScrollDelegate(self)
        ElStyleSheet.LINE_EDIT.apply(self)
        setFont(self)

    def contextMenuEvent(self, e):
        menu = TextEditMenu(self)
        menu.exec(e.globalPos())


class ElTextBrowser(QTextBrowser):
    """ Text browser """

    def __init__(self, parent=None):
        super().__init__(parent)
        self.scrollDelegate = SmoothScrollDelegate(self)
        ElStyleSheet.LINE_EDIT.apply(self)
        setFont(self)

    def contextMenuEvent(self, e):
        menu = TextEditMenu(self)
        menu.exec(e.globalPos())


class ElPasswordLineEdit(ElLineEdit):
    """ Password line edit """

    def __init__(self, parent=None):
        super().__init__(parent)
        self.viewButton = LineEditButton(FIF.VIEW, self)
        self.viewButton.setFixedSize(30, 30)

        self.setEchoMode(QLineEdit.Password)
        self.setContextMenuPolicy(Qt.NoContextMenu)
        self.hBoxLayout.addWidget(self.viewButton, 0, Qt.AlignRight)
        self.setClearButtonEnabled(False)

        self.viewButton.installEventFilter(self)
        self.viewButton.setIconSize(QSize(13, 13))
        self.viewButton.setFixedSize(29, 25)

    def setPasswordVisible(self, isVisible: bool):
        """ set the visibility of password """
        if isVisible:
            self.setEchoMode(QLineEdit.Normal)
        else:
            self.setEchoMode(QLineEdit.Password)

    def isPasswordVisible(self):
        return self.echoMode() == QLineEdit.Normal

    def setClearButtonEnabled(self, enable: bool):
        self._isClearButtonEnabled = enable

        if self.viewButton.isHidden():
            self.setTextMargins(0, 0, 28 * enable, 0)
        else:
            self.setTextMargins(0, 0, 28 * enable + 30, 0)

    def setViewPasswordButtonVisible(self, isVisible: bool):
        """ set the visibility of view password button """
        self.viewButton.setVisible(isVisible)

    def eventFilter(self, obj, e):
        if obj is not self.viewButton or not self.isEnabled():
            return super().eventFilter(obj, e)

        if e.type() == QEvent.MouseButtonPress:
            self.setPasswordVisible(True)
        elif e.type() == QEvent.MouseButtonRelease:
            self.setPasswordVisible(False)

        return super().eventFilter(obj, e)

    def inputMethodQuery(self, query: Qt.InputMethodQuery):
        # Disable IME for PasswordLineEdit
        if query == Qt.InputMethodQuery.ImEnabled:
            return False
        else:
            return super().inputMethodQuery(query)

    passwordVisible = Property(bool, isPasswordVisible, setPasswordVisible)
